package cn.wjssl.domain.award.service.distribute.impl;

import cn.wjssl.domain.award.model.aggregate.GiveOutPrizesAggregate;
import cn.wjssl.domain.award.model.entity.DistributeAwardEntity;
import cn.wjssl.domain.award.model.entity.UserAwardRecordEntity;
import cn.wjssl.domain.award.model.entity.UserCreditAwardEntity;
import cn.wjssl.domain.award.model.valobj.AwardStateVO;
import cn.wjssl.domain.award.repository.IAwardRepository;
import cn.wjssl.domain.award.service.distribute.IDistributeAward;
import cn.wjssl.types.common.Constants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.MathContext;

/**
 * 用户积分奖品，支持 award_config 透传，满足黑名单积分奖励。
 * 定义bean名字, 在使用时, 可以通过map注入获取对应奖品类型的发放处理, 类似于过滤器
 */
@Slf4j
@Component("user_credit_random")
public class UserCreditRandomAward implements IDistributeAward {

    @Resource
    private IAwardRepository repository;

    @Override
    public void giveOutPrizes(DistributeAwardEntity distributeAwardEntity) {
        /**
         * 1. 获取奖品的配置 awardConfig
         * 优先从流转实体类 distributeAwardEntity 中获取, 没有的话再从数据库中获取, 查询的是 award 表
         */
        Integer awardId = distributeAwardEntity.getAwardId();
        String awardConfig = distributeAwardEntity.getAwardConfig();
        if (StringUtils.isBlank(awardConfig)) {
            awardConfig = repository.queryAwardConfig(awardId); // 随机积分奖品的config 为积分区间 --> 1,100
        }

        // 2. 对配置格式进行判断, 如果分割后的数组长度不是2, 那就说明不是范围
        String[] creditRange = awardConfig.split(Constants.SPLIT);
        if (creditRange.length != 2) {
            throw new RuntimeException("award_config 「" + awardConfig + "」配置不是一个范围值，如 1,100");
        }

        // 3. 生成随机积分数
        BigDecimal creditAmount = generateRandom(new BigDecimal(creditRange[0]), new BigDecimal(creditRange[1]));

        /**
         * 4. 创建聚合对象, 更新数据库的中奖记录和用户积分账户
         * 用户中奖记录实体 UserAwardRecordEntity
         * 用户积分账户实体 UserCreditAwardEntity
         */
        UserAwardRecordEntity recordEntity = UserAwardRecordEntity.builder()
                .userId(distributeAwardEntity.getUserId())
                .awardId(distributeAwardEntity.getAwardId())
                .orderId(distributeAwardEntity.getOrderId())
                .awardState(AwardStateVO.complete)  // 这里奖品发放完成, 更新记录为complete
                .build();

        UserCreditAwardEntity userCreditEntity = UserCreditAwardEntity.builder()
                .userId(distributeAwardEntity.getUserId())
                .creditAmount(creditAmount)
                .build();

        GiveOutPrizesAggregate aggregate = GiveOutPrizesAggregate.builder()
                .userId(distributeAwardEntity.getUserId())
                .userAwardRecordEntity(recordEntity)
                .userCreditAwardEntity(userCreditEntity)
                .build();

        // 5. 更新中奖记录和用户账户积分
        repository.saveGiveOutPrizesAggregate(aggregate);

    }

    // 生成随机积分方法
    private BigDecimal generateRandom(BigDecimal min, BigDecimal max) {
        if (min.equals(max)) return min;
        BigDecimal randomBigDecimal = min.add(BigDecimal.valueOf(Math.random()).multiply(max.subtract(min)));
        return randomBigDecimal.round(new MathContext(3));
    }
}
